package co.edu.usbcali.presentation.backEndBeans;

import co.edu.usbcali.exceptions.*;
import co.edu.usbcali.modelo.*;
import co.edu.usbcali.modelo.dto.PracticanteDTO;
import co.edu.usbcali.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;

/**
 * 
 * @author Zathura Code Generator http://code.google.com/p/zathura
 * 
 */
public class PracticanteView extends DataSource implements Renderable,
		DisposableBean {
	private HtmlInputText txtApellidoPra;
	private HtmlInputText txtCelularPra;
	private HtmlInputText txtEmailPra;
	private HtmlInputText txtJornadaPra;
	private HtmlInputText txtNombrePra;
	private HtmlInputText txtSemestrePra;
	private HtmlInputText txtTelFijoPra;
	private HtmlSelectOneMenu cbbProgramaAcademico;
	private List<SelectItem> listaProgramaAcademico;
	private HtmlInputText txtCodPra;
	private HtmlCommandButton btnSave;
	private HtmlCommandButton btnModify;
	private HtmlCommandButton btnDelete;
	private HtmlCommandButton btnClear;
	private boolean renderDataTable;
	private boolean flag = true;
	private RenderManager renderManager;
	private PersistentFacesState state = PersistentFacesState.getInstance();
	private List<Practicante> practicante;
	private List<PracticanteDTO> practicanteDTO;

	public PracticanteView() {
		super("");
	}

	public String action_clear() {
		txtApellidoPra.setValue(null);
		txtApellidoPra.setDisabled(true);
		txtCelularPra.setValue(null);
		txtCelularPra.setDisabled(true);
		txtEmailPra.setValue(null);
		txtEmailPra.setDisabled(true);
		txtJornadaPra.setValue(null);
		txtJornadaPra.setDisabled(true);
		txtNombrePra.setValue(null);
		txtNombrePra.setDisabled(true);
		txtSemestrePra.setValue(null);
		txtSemestrePra.setDisabled(true);
		txtTelFijoPra.setValue(null);
		txtTelFijoPra.setDisabled(true);
		cbbProgramaAcademico.setValue(null);
		cbbProgramaAcademico.setDisabled(true);
		txtCodPra.setValue(null);
		txtCodPra.setDisabled(false);
		btnSave.setDisabled(true);
		btnDelete.setDisabled(true);
		btnModify.setDisabled(true);
		btnClear.setDisabled(false);

		return "";
	}

	public void listener_txtId(ValueChangeEvent event) {
		if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
			Practicante entity = null;

			try {
				Long codPra = new Long(txtCodPra.getValue().toString());
				entity = BusinessDelegatorView.getPracticante(codPra);
			} catch (Exception e) {
				// TODO: handle exception
			}

			if (entity == null) {
				txtApellidoPra.setDisabled(false);
				txtCelularPra.setDisabled(false);
				txtEmailPra.setDisabled(false);
				txtJornadaPra.setDisabled(false);
				txtNombrePra.setDisabled(false);
				txtSemestrePra.setDisabled(false);
				txtTelFijoPra.setDisabled(false);
				cbbProgramaAcademico.setDisabled(false);
				txtCodPra.setDisabled(false);
				btnSave.setDisabled(false);
				btnDelete.setDisabled(true);
				btnModify.setDisabled(true);
				btnClear.setDisabled(false);
			} else {
				txtApellidoPra.setValue(entity.getApellidoPra());
				txtApellidoPra.setDisabled(false);
				txtCelularPra.setValue(entity.getCelularPra());
				txtCelularPra.setDisabled(false);
				txtEmailPra.setValue(entity.getEmailPra());
				txtEmailPra.setDisabled(false);
				txtJornadaPra.setValue(entity.getJornadaPra());
				txtJornadaPra.setDisabled(false);
				txtNombrePra.setValue(entity.getNombrePra());
				txtNombrePra.setDisabled(false);
				txtSemestrePra.setValue(entity.getSemestrePra());
				txtSemestrePra.setDisabled(false);
				txtTelFijoPra.setValue(entity.getTelFijoPra());
				txtTelFijoPra.setDisabled(false);
				cbbProgramaAcademico.setValue(entity.getProgramaAcademico()
						.getCodigoPrograma());
				cbbProgramaAcademico.setDisabled(false);
				txtCodPra.setValue(entity.getCodPra());
				txtCodPra.setDisabled(true);
				btnSave.setDisabled(true);
				btnDelete.setDisabled(false);
				btnModify.setDisabled(false);
				btnClear.setDisabled(false);
			}
		}
	}

	public String action_save() {
		try {
			BusinessDelegatorView.savePracticante(FacesUtils
					.checkString(txtApellidoPra), FacesUtils
					.checkString(txtCelularPra), FacesUtils
					.checkLong(txtCodPra), FacesUtils.checkString(txtEmailPra),
					FacesUtils.checkString(txtJornadaPra), FacesUtils
							.checkString(txtNombrePra), FacesUtils
							.checkLong(txtSemestrePra), FacesUtils
							.checkString(txtTelFijoPra), null, null, FacesUtils
							.checkLong(cbbProgramaAcademico));
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_delete() {
		try {
			BusinessDelegatorView.deletePracticante(FacesUtils
					.checkLong(txtCodPra));
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modify() {
		try {
			BusinessDelegatorView.updatePracticante(FacesUtils
					.checkString(txtApellidoPra), FacesUtils
					.checkString(txtCelularPra), FacesUtils
					.checkLong(txtCodPra), FacesUtils.checkString(txtEmailPra),
					FacesUtils.checkString(txtJornadaPra), FacesUtils
							.checkString(txtNombrePra), FacesUtils
							.checkLong(txtSemestrePra), FacesUtils
							.checkString(txtTelFijoPra), null, null, FacesUtils
							.checkLong(cbbProgramaAcademico));
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modifyWitDTO(String apellidoPra, String celularPra,
			Long codPra, String emailPra, String jornadaPra, String nombrePra,
			Long semestrePra, String telFijoPra, Long codigoCue_Cuenta,
			Long codDocente_Docente, Long codigoPrograma_ProgramaAcademico)
			throws Exception {
		try {
			BusinessDelegatorView.updatePracticante(apellidoPra, celularPra,
					codPra, emailPra, jornadaPra, nombrePra, semestrePra,
					telFijoPra, codigoCue_Cuenta, codDocente_Docente,
					codigoPrograma_ProgramaAcademico);
			renderManager.getOnDemandRenderer("PracticanteView")
					.requestRender();
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
		} catch (Exception e) {
			// renderManager.getOnDemandRenderer("PracticanteView").requestRender();
			FacesUtils.addErrorMessage(e.getMessage());
			throw e;
		}

		return "";
	}

	public List<Practicante> getPracticante() {
		if (flag) {
			try {
				practicante = BusinessDelegatorView.getPracticante();
				flag = false;
			} catch (Exception e) {
				flag = true;
				FacesUtils.addErrorMessage(e.getMessage());
			}
		}

		return practicante;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setPracticante(List<Practicante> practicante) {
		this.practicante = practicante;
	}

	public boolean isRenderDataTable() {
		try {
			if (flag) {
				if (BusinessDelegatorView.findTotalNumberPracticante() > 0) {
					renderDataTable = true;
				} else {
					renderDataTable = false;
				}
			}

			flag = false;
		} catch (Exception e) {
			renderDataTable = false;
			e.printStackTrace();
		}

		return renderDataTable;
	}

	public DataModel getData() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModel(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<Practicante> getDataPage(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberPracticante = 0;

		try {
			totalNumberPracticante = BusinessDelegatorView
					.findTotalNumberPracticante().intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberPracticante) {
			endIndex = totalNumberPracticante;
		}

		try {
			practicante = BusinessDelegatorView.findPagePracticante(
					sortColumnName, sortAscending, startRow, endIndex
							- startRow);

			// Remove this Renderable from the existing render groups.
			// leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		// joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate JPA. If the EntityManager is
		// not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the cache in the DAO.
		// EntityManagerHelper.getEntityManager().clear();
		flag = true;

		return new DataPage<Practicante>(totalNumberPracticante, startRow,
				practicante);
	}

	public DataModel getDataDTO() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModelDTO(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<PracticanteDTO> getDataPageDTO(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberPracticante = 0;

		try {
			totalNumberPracticante = BusinessDelegatorView
					.findTotalNumberPracticante().intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberPracticante) {
			endIndex = totalNumberPracticante;
		}

		try {
			practicante = BusinessDelegatorView.findPagePracticante(
					sortColumnName, sortAscending, startRow, endIndex
							- startRow);

			if (Utilities.validationsList(practicante)) {
				practicanteDTO = new ArrayList<PracticanteDTO>();

				for (Practicante practicanteTmp : practicante) {
					PracticanteDTO practicanteDTO2 = new PracticanteDTO();
					practicanteDTO2.setCodPra(practicanteTmp.getCodPra()
							.toString());
					practicanteDTO2.setApellidoPra((practicanteTmp
							.getApellidoPra() != null) ? practicanteTmp
							.getApellidoPra().toString() : null);
					practicanteDTO2.setCelularPra((practicanteTmp
							.getCelularPra() != null) ? practicanteTmp
							.getCelularPra().toString() : null);
					practicanteDTO2
							.setEmailPra((practicanteTmp.getEmailPra() != null) ? practicanteTmp
									.getEmailPra().toString()
									: null);
					practicanteDTO2.setJornadaPra((practicanteTmp
							.getJornadaPra() != null) ? practicanteTmp
							.getJornadaPra().toString() : null);
					practicanteDTO2
							.setNombrePra((practicanteTmp.getNombrePra() != null) ? practicanteTmp
									.getNombrePra().toString()
									: null);
					practicanteDTO2.setSemestrePra((practicanteTmp
							.getSemestrePra() != null) ? practicanteTmp
							.getSemestrePra().toString() : null);
					practicanteDTO2.setTelFijoPra((practicanteTmp
							.getTelFijoPra() != null) ? practicanteTmp
							.getTelFijoPra().toString() : null);
					practicanteDTO2
							.setCodigoCue_Cuenta((practicanteTmp.getCuenta()
									.getCodigoCue() != null) ? practicanteTmp
									.getCuenta().getCodigoCue().toString()
									: null);
					practicanteDTO2
							.setCodDocente_Docente((practicanteTmp.getDocente()
									.getCodDocente() != null) ? practicanteTmp
									.getDocente().getCodDocente().toString()
									: null);
					practicanteDTO2
							.setCodigoPrograma_ProgramaAcademico((practicanteTmp
									.getProgramaAcademico().getCodigoPrograma() != null) ? practicanteTmp
									.getProgramaAcademico().getCodigoPrograma()
									.toString()
									: null);
					practicanteDTO2.setPracticante(practicanteTmp);
					practicanteDTO2.setPracticanteView(this);
					practicanteDTO.add(practicanteDTO2);
				}
			}

			// Remove this Renderable from the existing render groups.
			leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate JPA. If the EntityManager is
		// not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the cache in the DAO.
		// EntityManagerHelper.getEntityManager().clear();
		flag = true;

		return new DataPage<PracticanteDTO>(totalNumberPracticante, startRow,
				practicanteDTO);
	}

	protected boolean isDefaultAscending(String sortColumn) {
		return true;
	}

	/**
	 * This method is called when a render call is made from the server. Render
	 * calls are only made to views containing an updated record. The data is
	 * marked as dirty to trigger a fetch of the updated record from the
	 * database before rendering takes place.
	 */
	public PersistentFacesState getState() {
		onePageDataModel.setDirtyData();

		return state;
	}

	/**
	 * This method is called from faces-config.xml with each new session.
	 */
	public void setRenderManager(RenderManager renderManager) {
		this.renderManager = renderManager;
	}

	public void renderingException(RenderingException arg0) {
		if (arg0 instanceof TransientRenderingException) {
		} else if (arg0 instanceof FatalRenderingException) {
			// Remove from existing Customer render groups.
			leaveRenderGroups();
		}
	}

	/**
	 * Remove this Renderable from existing uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void leaveRenderGroups() {
		if (Utilities.validationsList(practicanteDTO)) {
			for (int i = 0; i < practicanteDTO.size(); i++) {
				renderManager.getOnDemandRenderer("PracticanteView").remove(
						this);
			}
		}
	}

	/**
	 * Add this Renderable to the new uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void joinRenderGroups() {
		if (Utilities.validationsList(practicanteDTO)) {
			for (int i = 0; i < practicanteDTO.size(); i++) {
				renderManager.getOnDemandRenderer("PracticanteView").add(this);
			}
		}
	}

	public void dispose() throws Exception {
	}

	public RenderManager getRenderManager() {
		return renderManager;
	}

	public void setState(PersistentFacesState state) {
		this.state = state;
	}

	public HtmlInputText getTxtApellidoPra() {
		return txtApellidoPra;
	}

	public void setTxtApellidoPra(HtmlInputText txtApellidoPra) {
		this.txtApellidoPra = txtApellidoPra;
	}

	public HtmlInputText getTxtCelularPra() {
		return txtCelularPra;
	}

	public void setTxtCelularPra(HtmlInputText txtCelularPra) {
		this.txtCelularPra = txtCelularPra;
	}

	public HtmlInputText getTxtEmailPra() {
		return txtEmailPra;
	}

	public void setTxtEmailPra(HtmlInputText txtEmailPra) {
		this.txtEmailPra = txtEmailPra;
	}

	public HtmlInputText getTxtJornadaPra() {
		return txtJornadaPra;
	}

	public void setTxtJornadaPra(HtmlInputText txtJornadaPra) {
		this.txtJornadaPra = txtJornadaPra;
	}

	public HtmlInputText getTxtNombrePra() {
		return txtNombrePra;
	}

	public void setTxtNombrePra(HtmlInputText txtNombrePra) {
		this.txtNombrePra = txtNombrePra;
	}

	public HtmlInputText getTxtSemestrePra() {
		return txtSemestrePra;
	}

	public void setTxtSemestrePra(HtmlInputText txtSemestrePra) {
		this.txtSemestrePra = txtSemestrePra;
	}

	public HtmlInputText getTxtTelFijoPra() {
		return txtTelFijoPra;
	}

	public void setTxtTelFijoPra(HtmlInputText txtTelFijoPra) {
		this.txtTelFijoPra = txtTelFijoPra;
	}

	public HtmlSelectOneMenu getCbbProgramaAcademico() {
		return cbbProgramaAcademico;
	}

	public void setCbbProgramaAcademico(HtmlSelectOneMenu cbbProgramaAcademico) {
		this.cbbProgramaAcademico = cbbProgramaAcademico;
	}

	public List<SelectItem> getListaProgramaAcademico() {
		listaProgramaAcademico = new ArrayList<SelectItem>();
		List<ProgramaAcademico> p;
		try {
			p = BusinessDelegatorView.getProgramaAcademico();
			for (int i = 0; i < p.size(); i++) {
				SelectItem si = new SelectItem(p.get(i).getCodigoPrograma(), p
						.get(i).getNombrePrograma());
				listaProgramaAcademico.add(si);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return listaProgramaAcademico;
	}

	public void setListaProgramaAcademico(
			List<SelectItem> listaProgramaAcademico) {
		this.listaProgramaAcademico = listaProgramaAcademico;
	}

	public HtmlInputText getTxtCodPra() {
		return txtCodPra;
	}

	public void setTxtCodPra(HtmlInputText txtCodPra) {
		this.txtCodPra = txtCodPra;
	}

	public HtmlCommandButton getBtnSave() {
		return btnSave;
	}

	public void setBtnSave(HtmlCommandButton btnSave) {
		this.btnSave = btnSave;
	}

	public HtmlCommandButton getBtnModify() {
		return btnModify;
	}

	public void setBtnModify(HtmlCommandButton btnModify) {
		this.btnModify = btnModify;
	}

	public HtmlCommandButton getBtnDelete() {
		return btnDelete;
	}

	public void setBtnDelete(HtmlCommandButton btnDelete) {
		this.btnDelete = btnDelete;
	}

	public HtmlCommandButton getBtnClear() {
		return btnClear;
	}

	public void setBtnClear(HtmlCommandButton btnClear) {
		this.btnClear = btnClear;
	}

	public void setRenderDataTable(boolean renderDataTable) {
		this.renderDataTable = renderDataTable;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public List<PracticanteDTO> getPracticanteDTO() {
		return practicanteDTO;
	}

	public void setPracticanteDTO(List<PracticanteDTO> practicanteDTO) {
		this.practicanteDTO = practicanteDTO;
	}

	public TimeZone getTimeZone() {
		return java.util.TimeZone.getDefault();
	}

	/**
	 * A special type of JSF DataModel to allow a datatable and datapaginator to
	 * page through a large set of data without having to hold the entire set of
	 * data in memory at once. Any time a managed bean wants to avoid holding an
	 * entire dataset, the managed bean declares this inner class which extends
	 * PagedListDataModel and implements the fetchData method. fetchData is
	 * called as needed when the table requires data that isn't available in the
	 * current data page held by this object. This requires the managed bean
	 * (and in general the business method that the managed bean uses) to
	 * provide the data wrapped in a DataPage object that provides info on the
	 * full size of the dataset.
	 */
	private class LocalDataModel extends PagedListDataModel {
		public LocalDataModel(int pageSize) {
			super(pageSize);
		}

		public DataPage<Practicante> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPage(startRow, pageSize);
		}
	}

	private class LocalDataModelDTO extends PagedListDataModel {
		public LocalDataModelDTO(int pageSize) {
			super(pageSize);
		}

		public DataPage<PracticanteDTO> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPageDTO(startRow, pageSize);
		}
	}
}
